(function($) {

    function DooDad(el, options) {
        this.el = $(el);
        this.log = []; // only the data for the log

        this.options = {
            ajaxOpts: {
                method: 'GET',
                dataType: 'json',
                timeout: 3000
            },
            sLogLevel: 'INFO',
            sLoadingMessage: 'Loading, please wait...'
        };

        this.setOptions(options);
        this.initialize();
    }

    $.fn.doodad = function(options) {
        return new DooDad(this.get(0), options);
    };


    $.fn.doodad.levels = {
        TRACE: 0,
        DEBUG: 1,
        INFO:  2,
        WARN:  3, 
        ERROR: 4,
        FATAL: 5
    };

    DooDad.prototype = {

        initialize: function() {
            var opts = this.options;
            var el = this.el;
            var me = this;

            var id = el.attr('id');

            el.wrap('<div id="' + id + '-wrapper"/>');

            // set up the actual log
            var loggerId = id + '-log';
            el.before('<div id="' + loggerId + '" class="doodad-log"/>');
            this.divLog = $('div#' + loggerId);

            // set up loader "please wait..."
            var loaderId = id + '-loading';
            el.before('<div id="' + loaderId + '" class="doodad-loader"/>');
            this.divLoading = $('div#' + loaderId);
            this.divLoading.append('<div id="' + id + '-loading-message" class="doodad-loader-message"></div>');
            $('#' + id + '-loading-message').html(opts.sLoadingMessage);
            //this.divLoading.append('<div align="center"><div id="' + id + '-loading-image" class="doodad-loader-image"></div></div>');
            this.divLoading.append('<div id="' + id + '-loading-image" class="doodad-loader-image"></div>');

            // initially hide content while loading
            var contentId = id + '-content';
            el.wrap('<div id="' + contentId + '" class="hidden"/>');
            this.divContent = $('div#' + contentId);

            //setTimeout( function() {me.load();}, 2000);
            me.load();
        },

        load: function() {
            var el       = this.el;
            var opts     = this.options;
            var ajaxOpts = opts.ajaxOpts;
            var me       = this;

            this.clearLog();
            this.divContent.addClass('hidden');
            this.divLoading.removeClass('hidden');

            ajaxOpts.success = function(json) {

                if (json.log != null && json.log.length > 0) {
                    me.log = $.map(json.log, function(el, i) { return el; });
                }

                setTimeout(function(){
                    me.renderLog();
                    me.fnSuccess(json);
                    me.divContent.removeClass('hidden');
                    me.divLoading.addClass('hidden');
                }, 2000);
                
            };

            ajaxOpts.error = function(req, textStatus, errorThrown) {
                me.error( 'Problem with ajax request: ' + req.status + ' - ' + req.statusText);
                //me.error( req.responseText );
                me.hideContent();
                me.hideLoader();
            };

            $.ajax( ajaxOpts );
        },

        renderLog: function() {
            var me = this;
            $.each(this.log, function(i, oLog) {
                me.logMessage(oLog);
            });
        },

        clearLog: function() {
            this.log = [];
            this.divLog.empty();
        },

        hideLog: function() {
            this.divLog.addClass('hidden');
        },

        showLog: function() {
            this.divLog.removeClass('hidden');
        },

        hideLoader: function() {
            this.divLoading.addClass('hidden');
        },

        showLoader: function() {
            this.divLoading.removeClass('hidden');
        },

        hideContent: function() {
            this.divContent.addClass('hidden');
        },

        showContent: function() {
            this.divContent.removeClass('hidden');
        },

        trace: function(sMessage) {
            this.logMessage( { sLogLevel: 'TRACE', sMessage: sMessage } ); 
        },
        debug: function(sMessage) {
            this.logMessage( { sLogLevel: 'DEBUG', sMessage: sMessage } ); 
        },
        info: function(sMessage) {
            this.logMessage( { sLogLevel: 'INFO', sMessage: sMessage } ); 
        },
        warn: function(sMessage) {
            this.logMessage( { sLogLevel: 'WARN', sMessage: sMessage } ); 
        },
        error: function(sMessage) {
            this.logMessage( { sLogLevel: 'ERROR', sMessage: sMessage } ); 
        },
        fatal: function(sMessage) {
            this.logMessage( { sLogLevel: 'FATAL', sMessage: sMessage } ); 
        },

        logMessage: function(oLogEntry) {
            var sMessage = oLogEntry.sMessage;
            var sLogLevel = oLogEntry.sLogLevel.toUpperCase();
            var iLogLevel = $.fn.doodad.levels[sLogLevel];

            if (iLogLevel >= this.minLogLevel) {
                this.divLog.append('<div class="doodad-log-entry doodad-log-' + sLogLevel + '">' + sMessage + '</div>');
            }
        },
            

        setOptions: function(opts) {
            this.options = $.extend(true,{}, this.options, opts);
            this.fnSuccess = opts.ajaxOpts.success;
            this.minLogLevel = $.fn.doodad.levels[this.options['sLogLevel']];
        }

    }; // end prototype
})(jQuery);
